package high.concurrent.config;

import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import high.concurrent.dto.MsgDto;
import high.concurrent.model.TxMsg;
import high.concurrent.service.TxMsgService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.List;

import static com.xxl.job.core.biz.model.ReturnT.SUCCESS;

@Slf4j
@Component
public class DeliverMsgJobHandler {

    @Autowired(required = false)
    private TxMsgService txMsgService;

    /**
     * ribbon 负载均衡客户端
     */
    @Autowired
    private LoadBalancerClient loadBalancerClient;

    /**
     * 过期时间 单位分钟
     */
    private static final int VERDUE_TIME=5;

    @XxlJob("deliverMsgJobHandler")
    public ReturnT<String> deliverMsgJobHandler(String s) throws Exception {

        log.info("进入投递定时任务..........................");

        this.processMsg();

        return SUCCESS;
    }

    public void processMsg(){

        //1.定时器轮询过期“待发送”状态的消息（过期消息一般是根据业务规则自行调整，例如 2min）
        List<TxMsg> msgList= this.txMsgService.selectOverdueMsgByNotSend(VERDUE_TIME);

        log.info("数据数量：" + msgList != null?String.valueOf(msgList.size()):"无数据");

        for(TxMsg msg:msgList){

            log.info("数据内容msg：" + msg.toString());

            //2.消息服务向支付服务发起状态查询，并且支付服务返回业务执行状态。
            boolean bo=this.checkMsg(msg);

            log.info("是否支付成功：" + bo);

            //true=已支付成功，把消息改为已发送，并发送消息
            // 3.消息服务对消息进行确认：如果业务执行成功，则发送MQ消息并更改消息状态为“已发送”
            if(bo){

                MsgDto msgDTO=new MsgDto();

                BeanUtils.copyProperties(msg,msgDTO);

                log.info("信息id：" + msgDTO.getMsgId());

                this.txMsgService.updateMsgDataByMsgService(msgDTO.getMsgId());

                log.info("支付成功：修改消息为已发送：");

            }else{

                //3.否则删除此条消息确保数据一致性。
                //直接删除消息
                MsgDto msgDTO=new MsgDto();

                msgDTO.setMsgId(msg.getMsgId());

                log.info("重复消息： 消息id: " + msg.getMsgId());

                this.txMsgService.delMsgDataByOrderNo(msgDTO);
            }
        }
    }

    /**
     * 消息服务向支付服务发起状态查询，并且支付服务返回业务执行状态。
     * @param msg
     * @return
     */
    public boolean checkMsg(TxMsg msg){

        log.info("robbon对象值：" + loadBalancerClient);
        //解析订单号
        String msgid=msg.getMsgId();

        String []array=msgid.split("_");

        String id=array[1];

        //调接口
        ServiceInstance si=loadBalancerClient.choose(msg.getAppName());
        StringBuffer sb=new StringBuffer("");
        sb.append("http://");
        sb.append(si.getHost());
        sb.append(":");
        sb.append(si.getPort());
        sb.append("/paycreate/checkMsg/");
        sb.append(id);

        log.info("回调服务地址：{}",sb.toString());
        RestTemplate restTemplate=new RestTemplate();
        Boolean bo = restTemplate.getForObject(sb.toString(), Boolean.class, "java");

        return bo;
    }
}